import {
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
  Mesh,
  AxesHelper,
  Color,
  GridHelper,
  Group,
  AnimationMixer,
  Clock,
  sRGBEncoding,
  AmbientLight,
  HemisphereLight,
  HemisphereLightHelper,
  DirectionalLight,
  DirectionalLightHelper,
  PlaneGeometry,
  MeshBasicMaterial,
  MeshLambertMaterial,
} from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

let camera: PerspectiveCamera, scene: Scene, renderer: WebGLRenderer;
let mixers: Array<AnimationMixer> = [];
let clock = new Clock();

init();
animate();

function init() {
  camera = new PerspectiveCamera(
    70,
    window.innerWidth / window.innerHeight,
    1,
    1000
  );
  camera.position.set(100, 0, 0);

  scene = new Scene();
  scene.background = new Color("#b0b0b0");

  // add ground
  let groundGeo = new PlaneGeometry(10000, 10000);
  let groundMat = new MeshLambertMaterial({color: '#fff'});
  let ground = new Mesh(groundGeo, groundMat);
  ground.position.y = -10;
  ground.rotateX(- Math.PI / 2);
  ground.receiveShadow =  true;
  scene.add(ground);

  // 1、添加上下背景灯光
  let hemiLight = new HemisphereLight('#fff','#fff', .6);
  hemiLight.color.set("#ffa1a1");
  hemiLight.groundColor.set("#fff");
  hemiLight.position.set(0, 150, 0);
  scene.add(hemiLight);

  // 2. add directional light
  let dirLight = new DirectionalLight( 0xffffff, 1 );
  dirLight.color.setHSL( 0.1, 1, 0.95 );
  dirLight.position.set( - 1, 1.75, 1 );
  dirLight.position.multiplyScalar( 30 );
  scene.add(dirLight);
  let dirLightHelper = new DirectionalLightHelper(dirLight, 10);
  scene.add(dirLightHelper);

  // 3. add shadow
  dirLight.castShadow = true;
  dirLight.shadow.mapSize.width = 2048;
  dirLight.shadow.mapSize.height = 2048;
  let size = 500;
  dirLight.shadow.camera.left = - size;
  dirLight.shadow.camera.right = size;
  dirLight.shadow.camera.top = size;
  dirLight.shadow.camera.bottom = - size;
  dirLight.shadow.camera.far = 3500;
  
  let hemiLightHelper = new HemisphereLightHelper(hemiLight, 10);
  scene.add(hemiLightHelper);


  new GLTFLoader().load(
    require("../static/modal/Flamingo.glb").default,
    (gltf) => {
      const mesh = gltf.scene.children[0];

      const s = 0.35;
      mesh.scale.set(s, s, s);
      mesh.position.y = 15;
      mesh.rotation.y = -1;

      mesh.castShadow = true;
      mesh.receiveShadow = true;

      // scene.add(mesh);
      for(let i = 0; i < 100; i++){
        let d1 =(1 - Math.random()) * 1000;
        let d2 =(1 - Math.random()) * 1000;
        let m = mesh.clone();
        m.position.x = d1;
        m.position.z = d2;
        scene.add(m);

        const mixer = new AnimationMixer(m);
        mixer.clipAction(gltf.animations[0]).setDuration(1).play();
        mixers.push(mixer);
      }

    }
  );

  renderer = new WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.outputEncoding = sRGBEncoding;
  renderer.shadowMap.enabled = true;
  document.body.appendChild(renderer.domElement);

  let control = new OrbitControls(camera, renderer.domElement);
  // renderer.render(scene, camera);
}

function animate() {
  requestAnimationFrame(animate);
  const delta = clock.getDelta();

  for (let i = 0; i < mixers.length; i++) {
    mixers[i].update(delta);
  }
  renderer.render(scene, camera);
}
